#ifndef TICK_H_
#define TICK_H_

#include <istream>
#include <cstdint>
#include <malloc.h>
#include "Utils.cpp"
#include "EesTraderDefine.h"
#include "spdlog/spdlog.h"
#include "spdlog/fmt/ostr.h"
#include <algorithm>
#include "Disruptor.h"
#include "BufComsumer.h"
#include<bitset>
#include<optional>
#include<shared_mutex>
#include <xgboost/c_api.h>
#include <dmlc/logging.h>
#include "DoubleDeque.cpp"
#include "FixedDeque.cpp"
#include "EESDataStruct.h"
#include "NanoNetShfeMdStruct.h"
#include <cfloat>

const double DECIMAL_FACTOR = 100.0;
enum OrderType {
    INSERT = 0, CANCEL = 1, INIT = 2
};
enum EventType {
    ORDER = 0, TICK = 1, STATUS = 2
};
using namespace std;
#pragma pack()

class Contract {
public:
    // 默认构造函数，使用空字符串初始化
    Contract() = default;

    // 使用 char* 参数的构造函数
    explicit Contract(const char *tmpData) {

        strncpy(this->data, tmpData, sizeof(this->data));
    }

    void initData(const char *tmpData) {
        strncpy(this->data, tmpData, sizeof(this->data));
    }

    // 重载 operator== 来比较两个 Contract 对象
    bool operator==(const Contract &other) const {
        return memcmp(this->data, other.data, sizeof(data)) == 0;
    }

    bool operator==(const char *tmpData) const {
        return memcmp(this->data, tmpData, sizeof(data)) == 0;
    }

    string to_str() const {
        string tmp(data);
        return tmp;
    }

private:
    char data[8]{}; // 大小为 8 的字符数组
};

class OrderEvent {
private:
public:
    EES_ClientToken m_ClientOrderToken = 0;
    short int eventType = 0; //1:orderAccept 2:marketAccept 3:deal 4:cancel -1:orderReject -2:marketReject -3: errorOrder -4:OrderCancelReject
    EES_OrderAcceptField *pOrderAccept = nullptr;
    EES_OrderMarketAcceptField *pMarketAccept = nullptr;
    EES_OrderExecutionField *pDeal = nullptr;
    EES_OrderCxled *pCancel = nullptr;
    EES_OrderRejectField *pOrderReject = nullptr;
    EES_CxlOrderRej *pCxlReject = nullptr;
    EES_OrderMarketRejectField *pOrderMarketReject = nullptr;
    mutable bool isFinished = false;

    OrderEvent() = default;

    ~OrderEvent() = default;

    void setOrderToken(EES_ClientToken token) {
        this->m_ClientOrderToken = token;
    }

    void setEventType(short int type) {
        this->eventType = type;
    }

    void clear() {
        this->eventType = 0;
        this->m_ClientOrderToken = 0;
        if (pOrderAccept != nullptr) {
            pOrderAccept = nullptr;
        }
        if (pMarketAccept != nullptr) {
            pMarketAccept = nullptr;
        }
        if (pDeal != nullptr) {
            pDeal = nullptr;
        }
        if (pCancel != nullptr) {
            pCancel = nullptr;
        }
        if (pCxlReject != nullptr) {
            pCxlReject = nullptr;
        }
        if (pOrderReject != nullptr) {
            pOrderReject = nullptr;
        }
        if (pOrderMarketReject != nullptr) {
            pOrderMarketReject = nullptr;
        }

    }

};

#ifdef __cplusplus
extern "C" {
#endif

typedef struct __attribute__((__packed__)) {
    int8_t ETH_IP_UDP[42];
    char inst_id[16];
    uint32_t update_time;
    uint32_t update_milli_sec;
    uint32_t change_no;
    uint32_t last_px;
    uint32_t volume;
    uint64_t turnover;
    uint64_t open_interest;
    uint32_t bid1_vol;
    uint32_t bid1_px;
    uint32_t bid2_vol;
    uint32_t bid2_px;
    uint32_t bid3_vol;
    uint32_t bid3_px;
    uint32_t bid4_vol;
    uint32_t bid4_px;
    uint32_t bid5_vol;
    uint32_t bid5_px;
    uint32_t ask1_vol;
    uint32_t ask1_px;
    uint32_t ask2_vol;
    uint32_t ask2_px;
    uint32_t ask3_vol;
    uint32_t ask3_px;
    uint32_t ask4_vol;
    uint32_t ask4_px;
    uint32_t ask5_vol;
    uint32_t ask5_px;
    uint64_t time;
    uint64_t cnt;
    uint32_t inst_no;
} shfe_md_t;

#ifdef __cplusplus
}
#endif

template<typename Key, typename Value>
class ThreadSafeMap {
public:
    // 插入键值对
    void insert(const Key &key, const Value &value) {
        std::unique_lock<std::shared_mutex> lock(mutex_);
        map_[key] = value;
    }

    void erase(const Key &key) {
        std::unique_lock<std::shared_mutex> lock(mutex_);
        map_.erase(key);
    }

    // 查找键值对
    bool find(const Key &key) {
        std::shared_lock<std::shared_mutex> lock(mutex_);
        auto it = map_.find(key);
        if (it != map_.end()) {
            return true;
        }
        return false;
    }

    Value &get(const Key &key) {
        std::shared_lock<std::shared_mutex> lock(mutex_);
        return map_[key];
    }

private:
    std::map<Key, Value> map_;
    std::shared_mutex mutex_;
};

struct ReqOrderMsg {
    req_cxl_order cxlOrder{};
    req_new_order enterOrder{};
    OrderType type = INIT;

    ReqOrderMsg() = default;

    ReqOrderMsg(char exchangeId, const string &contractCode, double price, unsigned int vol, char flag,
                EES_ClientToken token) {
        type = INSERT;
        strcpy(enterOrder.m_symbol, contractCode.c_str());
        enterOrder.m_side = flag;
        enterOrder.m_price = price;
        enterOrder.m_quantity = vol;
        enterOrder.m_clientToken = token;
        enterOrder.m_exchange = exchangeId;
    }

    void initByOrder(char exchangeId, const string &contractCode, double price, unsigned int vol, char flag,
                     EES_ClientToken token, Int2 basketId) {
        type = INSERT;
        strncpy(enterOrder.m_symbol, contractCode.c_str(), 8);
        enterOrder.m_side = flag;
        enterOrder.m_price = price;
        enterOrder.m_quantity = vol;
        enterOrder.m_clientToken = token;
        enterOrder.m_exchange = exchangeId;
        enterOrder.m_BasketID = basketId;
    }

    explicit ReqOrderMsg(EES_ClientToken m_clientToken, long long eesMarketToken) {
        type = CANCEL;
        cxlOrder.m_clientToken = m_clientToken;
        cxlOrder.m_order_reference_num = eesMarketToken;
    }

    void initByCancel(const EES_ClientToken m_clientToken, const long long eesMarketToken) {
        type = CANCEL;
        cxlOrder.m_clientToken = m_clientToken;
        cxlOrder.m_order_reference_num = eesMarketToken;
    }
};

class ReqOrderField {
public:
    EES_CancelOrder cancelOrder{};
    EES_EnterOrderField enterOrder{};
    OrderType type = INIT;

    ReqOrderField() = default;

    explicit ReqOrderField(long long int Ees_orderId) {
        type = CANCEL;
        cancelOrder.m_Quantity = 0;
        cancelOrder.m_MarketOrderToken = Ees_orderId;
    }

    ReqOrderField(char exchangeId, const string &contractCode, double price, unsigned int vol, char flag,
                  EES_ClientToken token) {
        type = INSERT;
        strcpy(enterOrder.m_Symbol, contractCode.c_str());
        enterOrder.m_Side = flag;
        enterOrder.m_Exchange = exchangeId;
        enterOrder.m_Price = price;
        enterOrder.m_Qty = vol;
        enterOrder.m_ForceMarketSessionId = true;
        enterOrder.m_ClientOrderToken = token;


    }


};

class TickDataHf {
private:
    tm md_time = {};

public:
    double ask_prices[5] = {DBL_MAX, DBL_MAX, DBL_MAX, DBL_MAX, DBL_MAX};
    double bid_prices[5] = {DBL_MIN, DBL_MIN, DBL_MIN, DBL_MIN, DBL_MIN};
    uint32_t ask_volumes[5] = {0};
    uint32_t bid_volumes[5] = {0};
    double ask_price = DBL_MAX;
    double bid_price = DBL_MIN;
    uint32_t volume = 0;
    double amount = 0;
    double open_interest = 0;
    double last_price = 0;
    char instrument_id[16] = {0};
    uint32_t update_time = 0;
    mutable uint64_t lastAmount = 0;
    mutable unsigned int lastVol = 0;
    mutable double lastAvgPrice = 0;
    uint16_t update_milli_sec = 0;
    int secondOfDay = 0;
    int hours = 0, minutes = 0, seconds = 0;

    TickDataHf() = default;

    const tm *get_mdtime() const {

        return &md_time;
    }

    double getAvgPrice(double multiple) const
    {
        return this->amount/(this->volume*multiple);
    }

    void fmtTime() {
        if (update_time > 0) {
            time_t now = this->update_time;
            localtime_r(&now, &md_time);
            hours = md_time.tm_hour;
            minutes = md_time.tm_min;
            seconds = md_time.tm_sec;
            secondOfDay = (hours * 60 + minutes) * 60 + seconds;
            // 取消时间判断

            // 开放时间判断

        }
    }

    bool isInOpenTime(int minute = 0) const {

        return (hours == 9 && minutes <= minute) ||
               (hours == 21 && minutes <= minute) ||
               (hours == 13 && minutes <= 30 + minute);
    }

    bool isInCancelTime() const {
        return (hours == 14 && minutes == 59 && seconds >= 59) ||
               (hours == 10 && minutes == 14 && seconds >= 59) ||
               (hours == 11 && minutes == 29 && seconds >= 59);
    }

    void initByTick(const TickDataHf &tick) {
        md_time = tick.md_time;
        last_price = tick.last_price;
        ask_price = tick.ask_price;
        bid_price = tick.bid_price;
        volume = tick.volume;
        open_interest = tick.open_interest;
        update_time = tick.update_time;
        update_milli_sec = tick.update_milli_sec;
        amount = tick.amount;
        lastAmount = tick.lastAmount;
        lastVol = tick.lastVol;
        lastAvgPrice = tick.lastAvgPrice;
        secondOfDay = tick.secondOfDay;
        std::memcpy(ask_prices, tick.ask_prices, sizeof(ask_prices));
        std::memcpy(bid_prices, tick.bid_prices, sizeof(bid_prices));
        std::memcpy(ask_volumes, tick.ask_volumes, sizeof(ask_volumes));
        std::memcpy(bid_volumes, tick.bid_volumes, sizeof(bid_volumes));
    }


    void initData(const NanoShfeMdType &p_md) {
        strncpy(instrument_id, p_md.inst_id, sizeof(instrument_id));

        last_price = p_md.last_px / DECIMAL_FACTOR;
        ask_price = p_md.ask1_px / DECIMAL_FACTOR;
        bid_price = p_md.bid1_px / DECIMAL_FACTOR;
        volume = p_md.volume;
        open_interest = p_md.open_interest;
        update_time = p_md.update_time;
        update_milli_sec = p_md.update_milli_sec;
        amount = p_md.turnover / DECIMAL_FACTOR;
        ask_prices[0] = ask_price;
        ask_volumes[0] = p_md.ask1_vol;
        bid_prices[0] = bid_price;
        bid_volumes[0] = p_md.bid1_vol;

        ask_prices[1] = p_md.ask2_px / DECIMAL_FACTOR;
        ask_volumes[1] = p_md.ask2_vol;
        bid_prices[1] = p_md.bid2_px / DECIMAL_FACTOR;
        bid_volumes[1] = p_md.bid2_vol;

        ask_prices[2] = p_md.ask3_px / DECIMAL_FACTOR;
        ask_volumes[2] = p_md.ask3_vol;
        bid_prices[2] = p_md.bid3_px / DECIMAL_FACTOR;
        bid_volumes[2] = p_md.bid3_vol;

        ask_prices[3] = p_md.ask4_px / DECIMAL_FACTOR;
        ask_volumes[3] = p_md.ask4_vol;
        bid_prices[3] = p_md.bid4_px / DECIMAL_FACTOR;
        bid_volumes[3] = p_md.bid4_vol;

        ask_prices[4] = p_md.ask5_px / DECIMAL_FACTOR;
        ask_volumes[4] = p_md.ask5_vol;
        bid_prices[4] = p_md.bid5_px / DECIMAL_FACTOR;
        bid_volumes[4] = p_md.bid5_vol;
    }

    friend ostream &operator<<(ostream &out, const TickDataHf &t) {
        json j;
        j["md_time"] = tm_to_string(t.md_time);
        j["instrument_id"] = t.instrument_id;
        j["ask_prices"] = t.ask_prices;
        j["bid_prices"] = t.bid_prices;
        j["ask_volumes"] = t.ask_volumes;
        j["bid_volumes"] = t.bid_volumes;
        j["ask_price"] = t.ask_price;
        j["bid_price"] = t.bid_price;
        j["volume"] = t.volume;
        j["amount"] = t.amount;
        j["open_interest"] = t.open_interest;
        j["last_price"] = t.last_price;
        j["update_time"] = t.update_time;
        j["lastAmount"] = t.lastAmount;
        j["lastVol"] = t.lastVol;
        j["lastAvgPrice"] = t.lastAvgPrice;
        j["update_milli_sec"] = t.update_milli_sec;
        out << j.dump(); // 4 是缩进级别，用于美化输出
        return out;
    }

    // 将 tm 结构体转换为字符串
    static std::string tm_to_string(const tm &md_time) {
        char time_str[20]; // 定义一个足够大的字符数组来存储结果
        // 使用 strftime 进行格式化
        // "%Y-%m-%d %H:%M:%S" 是输出格式
        if (strftime(time_str, sizeof(time_str), "%Y-%m-%d %H:%M:%S", &md_time) > 0) {
            return std::string(time_str);
        } else {
            return ""; // 或者可以返回一个错误消息
        }
    }


};

class SpecialLine {
public:
    uint32_t update_miltime = 0; // 当前时间，秒计数
    double last_price = 0;
    uint32_t volume = 0;
    uint32_t open_interest = 0;

    SpecialLine() = default;

    explicit SpecialLine(const TickDataHf &tick) {
        this->update_miltime = tick.update_time;
        this->last_price = tick.last_price;
        this->volume = tick.volume;
        this->open_interest = tick.open_interest;
    }
};

class OrderData {
public:
    unsigned char exchangeId = 0;
    string m_Account;
    string contractCode;
    unsigned char side = 0;
    unsigned int vol = 0;
    unsigned remainVol = 0;
    unsigned int dealVol = 0;
    unsigned int sumDealVol = 0;
    double sumDealPrice = 0;
    double dealPrice = 0;
    EES_ClientToken clientToken = 0;
    unsigned long long eesMarketToken = 0;
    EES_MarketOrderId eesMarketOrderId = {0};
    int noIdTimes = 0;
    double inputPrice = 0.0;
    bool isFak = false;

    EES_CustomFieldType customId = 0;
    int m_ExchangeErrorId = 0;

    EES_ReasonText2 m_ReasonText{};

    unsigned int m_ReasonCode = 0;
    //mutable  bool isFinished= false;
    mutable bool isCanceled = false;
    short int eventType = 0; //1:orderAccept 2:marketAccept 3:deal 4:cancel -1:orderReject -2:marketReject -3: errorOrder -4:OrderCancelReject

    OrderData() = default;

    explicit OrderData(const ReqOrderField &order) {
        this->exchangeId = order.enterOrder.m_Exchange;
        this->eesMarketToken = 0;
        this->contractCode = order.enterOrder.m_Symbol;
        this->inputPrice = order.enterOrder.m_Price;
        this->vol = order.enterOrder.m_Qty;
        this->remainVol = order.enterOrder.m_Qty;
        this->side = order.enterOrder.m_Side;
        this->clientToken = order.enterOrder.m_ClientOrderToken;
    }

    OrderData(unsigned char exchangeId, const string &contractCode, double price, unsigned int vol, char flag,
              unsigned int clientToken) {
        this->exchangeId = exchangeId;
        this->eesMarketToken = 0;
        this->contractCode = contractCode;
        this->inputPrice = price;
        this->vol = vol;
        this->remainVol = vol;
        this->side = flag;
        this->clientToken = clientToken;
    }

    ~OrderData() = default;

    bool isBuy() const {
        if (this->side == EES_SideType_open_long || side == EES_SideType_close_short ||
            side == EES_SideType_close_today_short || side == EES_SideType_close_ovn_short) {
            return true;
        }
        return false;
    }

    bool isSell() const {
        if (this->side == EES_SideType_open_short || side == EES_SideType_close_long ||
            side == EES_SideType_close_today_long || side == EES_SideType_close_ovn_long) {
            return true;
        }
        return false;
    }

    bool isOpen() const {
        return (this->side == EES_SideType_open_short || side == EES_SideType_open_long);

    }

    bool isClose() const {
        return (this->side == EES_SideType_close_long || this->side == EES_SideType_close_today_long ||
                this->side == EES_SideType_close_ovn_long ||
                this->side == EES_SideType_close_short || this->side == EES_SideType_close_today_short ||
                this->side == EES_SideType_close_ovn_short);
    }

    void initByOrderAccept(const EES_OrderAcceptField *pOrderAccept) {
        this->eventType = 1;
        m_Account = pOrderAccept->m_Account;
        this->contractCode = pOrderAccept->m_Symbol;
        vol = pOrderAccept->m_Qty;
        remainVol = pOrderAccept->m_Qty;
        inputPrice = pOrderAccept->m_Price;
        eesMarketToken = pOrderAccept->m_MarketOrderToken;
        side = pOrderAccept->m_Side;
        clientToken = pOrderAccept->m_ClientOrderToken;
        customId = pOrderAccept->m_CustomField;
        if (pOrderAccept->m_Tif == 0) {
            this->isFak = true;
        }
    }

    void initByMarketAccept(const string &contractCode, const EES_OrderMarketAcceptField *pAccept) {
        this->contractCode = contractCode;
        this->eventType = 2;
        this->clientToken = pAccept->m_ClientOrderToken;
        this->eesMarketToken = pAccept->m_MarketOrderToken;
        //strcpy(eesMarketOrderId, pAccept->m_MarketOrderId);
    }

    void initByOrderExecution(const string &contractCode, const EES_OrderExecutionField *p_exeField) {
        this->contractCode = contractCode;
        this->eventType = 3;
        this->dealVol = p_exeField->m_Quantity;
        this->dealPrice = p_exeField->m_Price;
        this->clientToken = p_exeField->m_ClientOrderToken;
        this->eesMarketToken = p_exeField->m_MarketOrderToken;
    }

    void initByOrderCxled(const string &contractCode, const EES_OrderCxled *pCxled) {
        this->contractCode = contractCode;
        this->eventType = 4;
        this->clientToken = pCxled->m_ClientOrderToken;
    }

    void initByOrderReject(const string &contractCode, const EES_OrderRejectField *pReject) {
        this->contractCode = contractCode;
        this->eventType = -1;
        this->clientToken = pReject->m_ClientOrderToken;
        this->m_ReasonCode = pReject->m_ReasonCode;
    }

    void initByMarketReject(const string &contractCode, const EES_OrderMarketRejectField *pReject) {
        this->contractCode = contractCode;
        this->eventType = -2;
        this->clientToken = pReject->m_ClientOrderToken;
        this->m_Account = pReject->m_Account;
        strcpy(this->m_ReasonText, pReject->m_ReasonText);
    }

    void initByOrderFailed(const string &contractCode, double price, unsigned int vol, EES_SideType flag,
                           unsigned int clientToken) {
        this->eventType = -3;
        this->eesMarketToken = 0;
        this->contractCode = contractCode;
        this->inputPrice = price;
        this->vol = vol;
        this->remainVol = vol;
        this->side = flag;
        this->clientToken = clientToken;
    }

    void initByCxlReject(const string &contractCode, const EES_CxlOrderRej *pReject) {
        this->contractCode = contractCode;
        this->eventType = -4;
        this->clientToken = pReject->m_ClientOrderToken;
        //this->m_Account=pReject->m_account;
        this->m_ReasonCode = pReject->m_ReasonCode;
    }

    void initByCxlFailed(const req_cxl_order &cancelOrder, int res) {
        this->eventType = -4;
        this->clientToken = cancelOrder.m_clientToken;
        this->eesMarketToken = cancelOrder.m_order_reference_num;
        this->m_ReasonCode = 100;
    }


    explicit OrderData(const EES_OrderAcceptField *pOrderAccept) {
        exchangeId = pOrderAccept->m_Exchange;
        m_Account = pOrderAccept->m_Account;
        this->contractCode = pOrderAccept->m_Symbol;
        vol = pOrderAccept->m_Qty;
        remainVol = pOrderAccept->m_Qty;
        inputPrice = pOrderAccept->m_Price;
        eesMarketToken = pOrderAccept->m_MarketOrderToken;
        side = pOrderAccept->m_Side;
        clientToken = pOrderAccept->m_ClientOrderToken;
        customId = pOrderAccept->m_CustomField;
        if (pOrderAccept->m_Tif == 0) {
            this->isFak = true;
        }

    }

    friend ostream &operator<<(ostream &os, const OrderData &o) {
        json j;
        j["exchangeId"] = int(o.exchangeId); // 可能需要转换为 int，取决于您的需求
        j["m_Account"] = o.m_Account;
        j["contractCode"] = o.contractCode;
        j["side"] = int(o.side); // 如果 side 有特殊含义，可能需要一个映射函数
        j["vol"] = o.vol;
        j["remainVol"] = o.remainVol;
        j["dealVol"] = o.dealVol;
        j["sumDealVol"] = o.sumDealVol;
        j["sumDealPrice"] = o.sumDealPrice;
        j["dealPrice"] = o.dealPrice;
        j["clientToken"] = o.clientToken;
        j["eesMarketToken"] = o.eesMarketToken;
        j["noIdTimes"] = o.noIdTimes;
        j["inputPrice"] = o.inputPrice;
        j["isFak"] = o.isFak;
        j["customId"] = o.customId;
        j["m_ExchangeErrorId"] = o.m_ExchangeErrorId;
        j["m_ReasonText"] = o.m_ReasonText;
        j["m_ReasonCode"] = o.m_ReasonCode;
        j["isCanceled"] = o.isCanceled;
        j["eventType"] = o.eventType;
        // 将 JSON 对象转换为字符串并输出
        os << j.dump(4); // 4 是缩进级别
        return os;
    }

};

class position {
public:
    position() = default;


    explicit position(const std::string &params) :
            contractCode(""), bkYdVol(0), skYdVol(0), bkTdVol(0), skTdVol(0) {
        try {
            auto j = json::parse(params);
            from_json(j, *this);
        } catch (const std::exception &e) {
            // 处理解析失败的情况
            std::cerr << "Error parsing JSON: " << e.what() << std::endl;
        }
    }

    void setParams(const std::string &params) {
        try {
            auto j = json::parse(params);
            from_json(j, *this);
        } catch (const std::exception &e) {
            std::cerr << "Error setting params from JSON: " << e.what() << std::endl;
        }
    }

    std::string contractCode;
    int bkYdVol = 0;
    int skYdVol = 0;
    int bkTdVol = 0;
    int skTdVol = 0;
    double sumBkPrice = 0;
    double sumSkPrice = 0;

    int getBkVol() const {
        return bkTdVol + bkYdVol;
    }

    double getBkPrice() const {
        if (getBkVol() == 0) {
            return 0;
        }
        return sumBkPrice / getBkVol();
    }
    int getSkVol() const {
        return skTdVol + skYdVol;
    }
    double getSkPrice() const {
        if (getSkVol() == 0) {
            return 0;
        }
        return sumSkPrice / getSkVol();
    }
    int getVol() const{
        return (getBkVol()-getSkVol());
    }



    friend void to_json(nlohmann::json &j, const position &p) {
        j = nlohmann::json{
                {"contractCode", p.contractCode},
                {"bkTdVol",      p.bkTdVol},
                {"bkYdVol",      p.bkYdVol},
                {"skTdVol",      p.skTdVol},
                {"skYdVol",      p.skYdVol},
                {"sumBkPrice",   p.sumBkPrice},
                {"sumSkPrice",   p.sumSkPrice}
        };
    }

    // 反序列化
    friend void from_json(const nlohmann::json &j, position &p) {
        j.at("contractCode").get_to(p.contractCode);
        j.at("bkTdVol").get_to(p.bkTdVol);
        j.at("bkYdVol").get_to(p.bkYdVol);
        j.at("skTdVol").get_to(p.skTdVol);
        j.at("skYdVol").get_to(p.skYdVol);
        j.at("sumBkPrice").get_to(p.sumBkPrice);
        j.at("sumSkPrice").get_to(p.sumSkPrice);
    }
    friend ostream &operator<<(ostream &os, const position &p) {
        nlohmann::json j;
        to_json(j, p);  // 使用已有的 to_json 函数
        os << j.dump(3);  // 将 JSON 对象转换为格式化的字符串，缩进为 4 个空格
        return os;
    }
};

class Event {
public:
    EventType type = ORDER;
    //OrderEvent orderEvent;
    TickDataHf tick;
    OrderData order;
    unsigned char m_InstrumentStatus = '0';    ///< 交易状态： '0':开盘前; '1':非交易; '2':连续交易; '3':集合竞价报单; '4'集合竞价价格平衡; '5':集合竞价撮合; '6': 收盘;
    char m_EnterTime[9] = {0};        ///< 进入本状态时间

    Event() = default;

    explicit Event(const string &contractCode) {
        order.contractCode = contractCode;
    }

    explicit Event(EES_SymbolStatus *pSymbolStatus) {
        this->type = STATUS;
        this->m_InstrumentStatus = pSymbolStatus->m_InstrumentStatus;
        strcpy(m_EnterTime, pSymbolStatus->m_EnterTime);
    }
};

#endif

